// Dep与Vue参数值:data属性(名/值)一一对应
class Dep {
    constructor() {
        this.subs = [];
        this._uid = (Math.random() * 100000000);
    }

    addSub(watcher = {}) {
        if (watcher.update) {
            this.subs.push(watcher);
        }
    }

    notify() {
        for (const watcher of this.subs) {
            watcher.update();
        }
    }
}

// Watcher与页面上Vue参数值:data属性的使用数目一一对应
// 当data属性值发生改变时，由Dep.notify函数通知调用Watcher.update函数，进行页面刷新
class Watcher {
    /**
     * 
     * @param {object} vm 
     * @param {object} data 
     * @param {function} callback 
     */
    constructor(vm = {}, key, callback) {
        this.callback = callback;
        Dep.target = this;
        this.vm = vm, this.key = key;
        // 通过vm[key]获取数据; 
        // this.valueSolve(key);
        // 改用Utils.value2props;
        const OldValues = Utils.value2props.call(this, key);
        Dep.target = null;
        this.OldValues = OldValues; // 个人添加成员属性
    }

    /**
     * 获取数据升级版函数
     * 后续参考vue-cli实现方式重写,定义与utils.js
     * this.vm[key]
     * 获取多层级数据
     * @param {string} attrs 
     */
    valueSolve(attrs = '') {
        const list2str = attrs.split('.');
        let NewVals = this.vm;
        for (const attrs of list2str || []) {
            const transit = NewVals[attrs];
            NewVals = transit ? transit : "";
        }
        return NewVals;
    }

    update() {
        // const NewValues = this.vm[this.key]; // 使用升级版获取数据函数
        const NewValues = this.valueSolve(this.key);
        if (this.callback) this.callback(NewValues);
        this.OldValues = NewValues; // 用于替换旧数据
    }
}